require 'backup'
require 'file_analyser'

class Fragmenter

  DEFAULT_SPLIT_SIZE = 700000000
  DEFAULT_NAME = "b"
  INFINITE = -1
  
  attr_accessor :split_size,:name
  attr_accessor :ignoring
  
  #``````````````````
  # constructor
  #``````````````````

  def initialize
    @split_size = DEFAULT_SPLIT_SIZE
    @name = DEFAULT_NAME
    @ignoring = []
  end  

  #``````````````````
  # interface
  #``````````````````

  def add(name,root)
    backup = Backup.new(name,root)
    fa = FileAnalyser.new
    fa.ignoring = @ignoring
    all_directories = fa.directories_in root
    all_directories.each do |directory|
      backup.add_qualified_directory(directory)
    end
    backup
  end

  def split(root)
  
    fa = FileAnalyser.new
    fa.ignoring = @ignoring
    
    running_count = 0
    all_files = []
    all_meta_files = []
    fa.files_in(root).each do |meta_file|
      file = FileAnalyser.path_of(meta_file)
      next if file.nil? or !File.file?(file)
      
      fa.load_config(meta_file)
      next if is_already_backed_up(fa.properties_of("backup"))
      
      new_file_size = fa.size_of(file)
      if running_count + new_file_size > @split_size and @split_size != INFINITE
        yield all_files

        time_stamp = "#{@name} #{Time.new}"      
        all_meta_files.each do |file|
          fa.load_config(file)
          fa.add_property("backup",time_stamp)
        end
        
        all_files = []
        all_meta_files = []
        running_count = 0
      end
      running_count += new_file_size
      all_files << file
      all_meta_files << meta_file
    end
    
    yield all_files if all_files.length > 0

  end

  
  #``````````````````
  # private methods
  #``````````````````  

  private


    def is_already_backed_up(all_properties)
      all_properties.each do |value|
        return true if value.split[0] == @name
      end
      return false
    end

    def latest_backup(all_backups)
      all_backups.length == 0 ? new_backup(all_backups) : all_backups.last
    end
  
    def new_backup(all_backups)
      name = "Disk#{all_backups.length + 1}"
      all_backups << Backup.new(name,@root)
      all_backups.last
    end
  
end
